package com.vxdata.utils.modules.utils.zstp;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.csv.CsvData;
import cn.hutool.core.text.csv.CsvReader;
import cn.hutool.core.text.csv.CsvRow;
import cn.hutool.core.text.csv.CsvUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 读取大型 csv 文件
 */
public class LargeCsvReadUtil {

    public static void main(String[] args) {
        // 指定 CSV 文件路径
        String filePath = "D:\\项目文件\\exchange\\dataset\\测试csv文件读取.csv";

        // 读取大文件
        System.out.println(readCsvMapList(filePath, null, null, "UTF-8", ","));

    }


    /**
     * 读取CSV大文件
     *
     * @param filePath       文件路径
     * @param contentIdList  第几行的数据
     * @param contentColName csv文件要查询的内容列
     * @param fieldDelimiter csv文件分隔符
     * @return
     */
    public static List<Map<String, Object>> readCsvMapList(String filePath, List<String> contentIdList, String contentColName, String encoding, String fieldDelimiter) {
        if (StringUtils.isNotEmpty(contentColName)) {
            contentColName = contentColName.replace("\"", "").replace("'", "");
        }
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), encoding))) {
            CsvReader csvReader = CsvUtil.getReader();
            csvReader.setContainsHeader(true); // 设置包含表头
            csvReader.setFieldSeparator(fieldDelimiter.charAt(0)); // 设置分隔符为逗号
            CsvData data = csvReader.read(reader);
            return readCsvMapList(data, contentIdList, contentColName);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("读取CSV文件失败, 失败原因: " + e.getMessage());
        }
    }

    /**
     * 读取CSV大文件
     *
     * @param reader         BufferedReader 字符缓冲流
     * @param contentIdList  第几行的数据
     * @param contentColName csv文件要查询的内容列
     * @param fieldDelimiter csv文件分隔符
     * @return
     */
    public static List<Map<String, Object>> readCsvMapList(BufferedReader reader, List<String> contentIdList, String contentColName, String fieldDelimiter) {
        if (StringUtils.isNotEmpty(contentColName)) {
            contentColName = contentColName.replace("\"", "").replace("'", "");
        }
        try {
            CsvReader csvReader = CsvUtil.getReader();
            csvReader.setContainsHeader(true); // 设置包含表头
            csvReader.setFieldSeparator(fieldDelimiter.charAt(0)); // 设置分隔符为逗号
            CsvData data = csvReader.read(reader);
            return readCsvMapList(data, contentIdList, contentColName);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("读取CSV文件map失败, 失败原因: " + e.getMessage());
        }
    }


    /**
     * 读取CSV文件
     *
     * @param data           csv数据
     * @param contentIdList  第几行的数据
     * @param contentColName csv文件要查询的内容列
     * @return
     */
    public static List<Map<String, Object>> readCsvMapList(CsvData data, List<String> contentIdList, String contentColName) {
        List<Map<String, Object>> mapList = new ArrayList<>();

        if (CollectionUtil.isEmpty(contentIdList)) {
            for (int i = 0; i < data.getRows().size(); i++) {
                CsvRow r = data.getRow(i);
                Map<String, Object> map = new LinkedHashMap<>();
                map.put("key", i + 2);
                if (StringUtils.isNotEmpty(contentColName)) {
                    map.put(contentColName, r.getByName(contentColName));
                } else {
                    r.getFieldMap().forEach((k, v) -> map.put(k, (Object) v));
                }
                mapList.add(map);
            }
        } else {
            for (String contentId : contentIdList) {
                Long flag = Long.valueOf(contentId) - 2;
                int rowCount = data.getRowCount();
                if (flag >= rowCount) {
                    continue;
                }
                CsvRow r = data.getRow(Math.toIntExact(flag));
                Map<String, Object> map = new LinkedHashMap<>();
                map.put("key", contentId);
                if (StringUtils.isNotEmpty(contentColName)) {
                    map.put(contentColName, r.getByName(contentColName));
                } else {
                    r.getFieldMap().forEach((k, v) -> map.put(k, (Object) v));
                }
                mapList.add(map);
            }
        }
        return mapList;
    }

}
